--[[IMVERSION=12
Made by:
Straight Up Merks]]


local IM = { };

-----------------------------
IM.CustomPrefix = "ominous";
-----------------------------

-------------------------------------------------------
--Osiris Code Below--
-------------------------------------------------------
surface.CreateFont("Verdana", {font="TabLarge", size=15, weight=700})

hook.Add("HUDPaint", "IMwatermark", function()
	draw.DrawText("Ominous Powered v12 (rel-GMOD13)", "Verdana", 10, 10, Color(255, 255, 255, 255), TEXT_ALIGN_LEFT, TEXT_ALIGN_LEFT)
end)

function IM.RandomString( len, numbers, special )
	local chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"..(numbers == true && "1234567890" or "")..(special == true && "!?@#$%^&*[](),.-+={}:;'\"<>|\\" or ""); --You can change the list if you like
	local result = "";
	
	if (len < 1) then
		len = math.random( 10, 20 );
	end
	
	for i = 1, len do
		result = result..string.char( string.byte( chars, math.random( 1, string.len( chars ) ) ) );
	end
	
	return tostring( result );
end

IM.MetaPlayer = FindMetaTable( "Player" );
IM.CreateClientConVar = CreateClientConVar;

local function CreateClientConVar( cvarname, default, save, onmenu )
	IM.CreateClientConVar( cvarname, default, save, false );
	return {cvar = GetConVar( cvarname ), OnMenu = onmenu, name = cvarname, main = string.find( cvarname, "enable" )};
end

IM.RandomPrefix = IM.CustomPrefix or IM.RandomString( math.random( 5, 8 ), false );
IM.DeadPlayers = { };
IM.Traitors = { };
IM.TWeaponsFound = { };
IM.Recoils = { };
IM.RandomHooks = { hook = { }, name = { } };
IM.ply = LocalPlayer;
IM.players = player.GetAll;
IM.Target = nil;
IM.mouse1 = false;
IM.AimbotKeyDown = false;
IM.CVARS = {Bools = { }, Numbers = { }};
IM.CVARS.Bools["Aimbot"] = CreateClientConVar( IM.RandomPrefix.."_aimbot_enabled", "0", true, true );
IM.CVARS.Bools["Aim on key"] = CreateClientConVar( IM.RandomPrefix.."_aim_on_key", "1", true, true );
IM.CVARS.Bools["Aim on mouse1"] = CreateClientConVar( IM.RandomPrefix.."_aim_on_mouse", "1", true, true );
IM.CVARS.Numbers["Max Angle"] = CreateClientConVar( IM.RandomPrefix.."_aimbot_max_angle", "30", true, true );
IM.CVARS.Bools["Aim at team mates"] = CreateClientConVar( IM.RandomPrefix.."_aimbot_friendly_fire", "1", true, true );
IM.CVARS.Bools["Aim at steam friends"] = CreateClientConVar( IM.RandomPrefix.."_aimbot_steam_friends", "0", true, true );
IM.CVARS.Bools["ESP"] = CreateClientConVar( IM.RandomPrefix.."_esp_enabled", "1", true, true );
IM.CVARS.Bools["ESP: Show health"] = CreateClientConVar( IM.RandomPrefix.."_esp_show_health", "1", true, true );
IM.CVARS.Bools["ESP: Show weapon"] = CreateClientConVar( IM.RandomPrefix.."_esp_show_weapon", "1", true, true );
IM.CVARS.Bools["ESP: Show name"] = CreateClientConVar( IM.RandomPrefix.."_esp_show_name", "1", true, true );
IM.CVARS.Bools["ESP: TTT Show traitors"] = CreateClientConVar( IM.RandomPrefix.."_esp_show_traitors", "1", true, true );
IM.CVARS.Bools["ESP: TTT Show dead bodies"] = CreateClientConVar( IM.RandomPrefix.."_esp_show_dead_bodies", "1", true, true );
IM.CVARS.Bools["ESP: TTT Show C4"] = CreateClientConVar( IM.RandomPrefix.."_esp_show_c4", "1", true, true );
IM.CVARS.Bools["ESP: GMODZ Show items"] = CreateClientConVar( IM.RandomPrefix.."_esp_show_gmodz_items", "1", true, true );
IM.CVARS.Bools["ESP: GMODZ Show inventories"] = CreateClientConVar( IM.RandomPrefix.."_esp_show_gmodz_inventories", "1", true, true );
IM.CVARS.Bools["Chams"] = CreateClientConVar( IM.RandomPrefix.."_chams_enabled", "1", true, true );
IM.CVARS.Bools["Crosshair"] = CreateClientConVar( IM.RandomPrefix.."_crosshair_enabled", "1", true, true );
IM.CVARS.Bools["No Recoil"] = CreateClientConVar( IM.RandomPrefix.."_no_recoil", "1", true, true );
IM.CVARS.Bools["No Visual Recoil"] = CreateClientConVar( IM.RandomPrefix.."_no_visual_recoil", "1", true, true );
IM.CVARS.Bools["Traitor Detector"] = CreateClientConVar( IM.RandomPrefix.."_traitor_detector", "1", true, true );
IM.CVARS.Bools["Show spectators"] = CreateClientConVar( IM.RandomPrefix.."_show_spectators", "1", true, true );
IM.CVARS.Bools["DarkRP Godmode(Broken ATM)"] = CreateClientConVar( IM.RandomPrefix.."_darkrp_god", "1", true, true );
IM.CVARS.Bools["Simplify spectator list"] = CreateClientConVar( IM.RandomPrefix.."_show_spectators_simplify", "0", true, true );
IM.CVARS.Bools["Bunny hop"] = CreateClientConVar( IM.RandomPrefix.."_bunnyhop", "1", true, true );
IM.Mat = CreateMaterial( string.lower( IM.RandomString( math.random( 5, 8 ), false, false ) ), "VertexLitGeneric", { ["$basetexture"] = "models/debug/debugwhite", ["$model"] = 1, ["$ignorez"] = 1 } ); --Last minute change
IM.HeadPos = nil;
IM.JumpReleased = false;
IM.TraceRes = nil;
IM.Font = nil;
IM.IsTraitor = nil;
IM.IsTTT = false;
IM.IsGmodZ = false;
IM.PrintEx = MsgC;
IM.LatestVersion = nil;
IM.Version = "8.0.3";
IM.V = 80; --DO NOT EDIT THIS
IM.TimerName = IM.RandomString( 0, false, false );
IM.Unloaded = false;
IM.ToggleFade = nil;

function IM.Init( )
	--Eww this is ugly
	IM.Font = IM.RandomString( 0, false, false );
	surface.CreateFont( IM.Font, { font = "Verdana", size = 14, weight = 750, antialias = false, outline = true } );
	IM.IsTTT = string.find( GAMEMODE.Name , "Terror" );
	IM.IsGmodZ = ( string.lower( GAMEMODE.Name ) == "gmodz" );
	
	RunConsoleCommand( "showconsole" );
	Msg( "\n\n\n" );
	IM.Print( true, true, Color( 25, 225, 80 ), "Loaded!", Color( 255, 255, 255 ), "\tv"..IM.Version );
	IM.Print( true, true, Color( 255, 255, 255 ), "Your random prefix is "..IM.RandomPrefix );
	IM.Print( true, true, Color( 255, 255, 255 ), "Checking for updates..." );
	IM.Print( true, true, Color( 255, 255, 255 ), "Made by: Straight Up Merks\n\n\n\n" );
	
	http.Fetch( "http://ominousgmod.googlecode.com/files/dong.lua", 
		function( HTML ) 
			local findpos = string.find( HTML, "OMVERSION=", 0, false );
			
			if (findpos) then
				local version = tonumber( string.sub( HTML, findpos+10, findpos+13 ) );
				if ( version > IM.V ) then
					IM.Print( true, true, Color( 255, 200, 200 ), "Your version is out of date!" );
					IM.LatestVersion = HTML;
					IM.UpdateMenu();
				else
					IM.Print( true, true, Color( 200, 255, 200 ), "Your version is up to date." );
				end
			end
		end,
		
		function() 
			IM.Error( "Failed checking for updates." );
		end
	);
	
	if (IM.IsTTT) then
		IM.IsTraitor = IM.MetaPlayer.IsTraitor
		
		function IM.MetaPlayer:IsTraitor()
			if (self == IM.ply()) then return IM.IsTraitor( self ); end
			
			if (!table.HasValue( IM.Traitors, self ) || !IM.CVARS.Bools["Traitor Detector"].cvar:GetBool()) then
				return IM.IsTraitor( self );
			else
				return true;
			end
		end
	end
end

function IM.Print( timestamp, stamp, ... )
	if (timestamp) then
		Msg( "["..os.date("%H:%M:%S").."] " );
	end
	
	if (stamp) then
		MsgC(Color( 154, 205, 50 ), "[Ominous]: " );
	end
	
	local t = {...};
	
	if (#t == 1) then
		IM.PrintEx( Color(255, 255, 255), t[1] );
	else
		for i = 1, #t, 2 do
			IM.PrintEx( t[i], t[i+1] );
		end
	end
	
	Msg('\n');
end

function IM.PrintChat( ... )
	chat.AddText( Color( 154, 205, 50 ), "[Ominous]: ", ... );
end

function IM.Error( error )
	Msg( "["..os.date("%H:%M:%S").."] " );
	MsgC( Color( 154, 205, 50 ), "[Ominous]: ERROR: " );
	MsgC( Color( 255, 255, 255 ), error.."\n" );
end
function IM.IsOnTeam( ply )
	if ( IM.IsTTT ) then
		return ply:IsTraitor() == IM.ply():IsTraitor();
	else
		return ply:Team() == IM.ply():Team();
	end
end

function IM.GetValidPlayers( )
	local players = { };
	
	for _, ply in pairs( IM.players() ) do
		if ( ply != IM.ply && IsValid( ply ) && 
		ply:IsPlayer() && 
		ply:Alive() && 
		ply:Health() >= 1 &&
		( ply:GetFriendStatus() != "friend" || IM.CVARS.Bools["Aim at steam friends"].cvar:GetBool() ) &&
		( !IM.IsOnTeam( ply ) || IM.CVARS.Bools["Aim at team mates"].cvar:GetBool() ) ) then
			table.insert( players, ply );
		end
	end
	
	return players
end

function IM.IsVisible( ply )
	if (!IsValid( ply )) then return false end
	
	local vecPos, _ = ply:GetBonePosition( ply:LookupBone( "ValveBiped.Bip01_Head1" ) or 12 );
	local trace = { start = IM.ply():EyePos(), endpos = vecPos, filter = IM.ply(), mask = MASK_SHOT };
	local traceRes = util.TraceLine( trace );
	
	IM.TraceRes = traceRes;
	
	if (traceRes.HitWorld || traceRes.Entity != ply) then return false end;
	
	return true;
end

function IM.ClosestAngle( players )
	local flAngleDifference = nil;
	local newAngle = nil;
	local viewAngles = IM.ply():EyeAngles();
	
	for _, ply in pairs( players ) do
		local vecPos, ang = ply:GetBonePosition( ply:LookupBone( "ValveBiped.Bip01_Head1" ) or 12 );
		local oldpos = vecPos;
		vecPos = vecPos - IM.VelocityPrediction( IM.ply() ) + IM.VelocityPrediction( ply )
		local angAngle = ( vecPos - IM.ply():EyePos() ):Angle()
		local flDif = math.abs( math.AngleDifference( angAngle.p, viewAngles.p ) ) + math.abs( math.AngleDifference( angAngle.y, viewAngles.y ) );
		
		if ((flAngleDifference == nil || flDif < flAngleDifference) && (!IM.CVARS.Numbers["Max Angle"].cvar:GetBool() || flDif < IM.CVARS.Numbers["Max Angle"].cvar:GetFloat())) then
			IM.HeadPos = oldpos:ToScreen();
			IM.Target = ply;
			flAngleDifference = flDif;
			newAngle = angAngle;
		end
	end
	
	return newAngle;
end

function IM.VelocityPrediction( ply ) return ply:GetAbsVelocity() * 0.012; end

function IM.Aimbot( )
	IM.HeadPos = nil;
	
	if (!IM.CVARS.Bools["Aimbot"].cvar:GetBool() || !IM.mouse1 && (IM.CVARS.Bools["Aim on key"].cvar:GetBool() == true || IM.CVARS.Bools["Aim on mouse1"].cvar:GetBool() == true) && !IM.AimbotKeyDown) then return end
	
	local players = {};
	
	for _, ply in pairs( IM.GetValidPlayers() ) do
		if (IM.IsVisible( ply )) then
			table.insert( players, ply );
		end
	end
	
	if (table.Count( players ) == 0) then 
		IM.Target = nil;
		return
	end;
	
	local newAngle = IM.ClosestAngle( players );
	
	if ( newAngle != nil ) then IM.ply():SetEyeAngles( newAngle ) end;
end

function IM.TableSortByDistance( former, latter ) return latter:GetPos():Distance( IM.ply():GetPos() ) > former:GetPos():Distance( IM.ply():GetPos() ) end
function IM.TableSortByAsc( former, latter ) print( "hey" ) return string.byte( string.lower( former.name ), 1 ) < string.byte( string.lower( latter.name ), 1 ) end

function IM.GetPlayersByDistance( )
	local players = IM.players( );
	
	table.sort( players, IM.TableSortByDistance );
	
	return players;
end

function IM.CreateMove( cmd )
	if (IM.IsTTT && IM.ply():Alive() && IM.ply():Health() >= 1 && IM.ply():Team() != TEAM_SPECTATOR) then
		IM.ply().voice_battery = 100; --Infinite voichat time I don't need to check if it's TTT because swag
	end
	
	if (cmd:KeyDown( IN_ATTACK ) && !IM.mouse1 && IM.CVARS.Bools["Aim on mouse1"].cvar:GetBool() == true ) then
		IM.mouse1 = true;
		IM.Aimbot( );
	elseif ( !cmd:KeyDown( IN_ATTACK ) && IM.mouse1 && IM.CVARS.Bools["Aim on mouse1"].cvar:GetBool() == true ) then
		IM.mouse1 = false;
	end
	
	if (IM.CVARS.Bools["No Recoil"].cvar:GetBool() && IsValid( IM.ply() ) && IM.ply():Alive() && IM.ply():Health() > 0 && IsValid( IM.ply():GetActiveWeapon() )) then
		if ( IM.ply():GetActiveWeapon().Primary && IM.ply():GetActiveWeapon().Primary.Recoil ) then
			IM.Recoils[IM.ply():GetActiveWeapon():EntIndex()] = IM.ply():GetActiveWeapon().Primary.Recoil;
			IM.ply():GetActiveWeapon().Primary.Recoil = 0;
		end
	end
	
	if (cmd:KeyDown( IN_JUMP )) then --Credits to gir489 original code for TF2
		if (!IM.JumpReleased) then
			if (IM.CVARS.Bools["Bunny hop"].cvar:GetBool() && !IM.ply():OnGround()) then
				cmd:RemoveKey( IN_JUMP );
			end
		else
			IM.JumpReleased = false
		end
	elseif (!IM.JumpReleased) then
		IM.JumpReleased = true;
	end
end

function IM.NoVisualRecoil( ply, pos, angles, fov )
   if (IM.CVARS.Bools["No Visual Recoil"].cvar:GetBool() && IM.ply():Health() > 0 && IM.ply():Team() != TEAM_SPECTATOR && IM.ply():Alive()) then
	   return GAMEMODE:CalcView( ply, IM.ply():EyePos(), IM.ply():EyeAngles(), fov, 0.1 );
   end
end

function IM.AddToColor( color, add )
	return color + add <= 255 and color + add or color + add - 255
end

function IM.SubtractFromColor( color, sub )
	return color - sub >= 0 and color - sub or color - sub + 255
end

function IM.ESP( ) 
	if (IM.ToggleFade or 0 > CurTime()) then
		draw.DrawText( "Aimbot: "..(IM.AimbotKeyDown and "on" or "off"), IM.Font, ScrW()/2, ScrH()/2, Color( 255, 255, 255, 255 * (IM.ToggleFade - CurTime()) ), 1 );
	end
	
	if (!IM.CVARS.Bools["Crosshair"].cvar:GetBool() && !IM.CVARS.Bools["ESP"].cvar:GetBool() && !IM.CVARS.Bools["Show spectators"].cvar:GetBool()) then return end;
	
	if ( IM.CVARS.Bools["Crosshair"].cvar:GetBool() ) then
		surface.SetDrawColor( Color( 255, 255, 255 ) );
		surface.DrawLine( ScrW()/2-10, ScrH()/2, ScrW()/2-4, ScrH()/2 );
		surface.DrawLine( ScrW()/2+10, ScrH()/2, ScrW()/2+4, ScrH()/2 );
		surface.DrawLine( ScrW()/2, ScrH()/2-10, ScrW()/2, ScrH()/2-4 );
		surface.DrawLine( ScrW()/2, ScrH()/2+10, ScrW()/2, ScrH()/2+4 );
	end
	
	if (IM.CVARS.Bools["Show spectators"].cvar:GetBool()) then
		local spectators = 0;
		for _, ply in pairs( IM.players() ) do
			if (ply != IM.ply() && (ply:GetObserverMode() == OBS_MODE_IN_EYE|| ply:GetObserverMode() == OBS_MODE_CHASE) && ply:GetObserverTarget() == IM.ply()) then
				if (spectators == 0 && !IM.CVARS.Bools["Simplify spectator list"].cvar:GetBool()) then
					draw.DrawText( "Spectating you: "..ply:Nick(), IM.Font, ScrW()/2, 25, Color( 255, 100, 50 ), 1 );
				elseif (!IM.CVARS.Bools["Simplify spectator list"].cvar:GetBool()) then
					draw.DrawText( ply:Nick(), IM.Font, ScrW()/2, 25 + spectators*13, Color( 255, 100, 50 ), 1 );
				else
					draw.DrawText( "Someone is spectating you Niggah!", IM.Font, ScrW()/2, 25, Color( 255, 100, 50 ), 1 );
					break;
				end
				
				spectators = spectators + 1;
			end
		end
	end
	
	if ( !IM.CVARS.Bools["ESP"].cvar:GetBool() ) then return end
	
	surface.SetFont( IM.Font );
	
	for _, ply in pairs( IM.players() ) do
		if (ply != IM.ply() && ply:Health() >= 1 && ply:Alive() && ply:Team() != TEAM_SPECTATOR) then
			local min, max = ply:GetRenderBounds();
			local pos = ply:GetPos() + Vector( 0, 0, ( min.z + max.z ) );
			local color = Color( 50, 255, 50, 255 );
			
			if ( ply:Health() <= 10 ) then color = Color( 255, 0, 0, 255 );
			elseif ( ply:Health() <= 20 ) then color = Color( 255, 50, 50, 255 );
			elseif ( ply:Health() <= 40 ) then color = Color( 250, 250, 50, 255 );
			elseif ( ply:Health() <= 60 ) then color = Color( 150, 250, 50, 255 ); 
			elseif ( ply:Health() <= 80 ) then color = Color( 100, 255, 50, 255 ); end
			
			pos = ( pos + Vector( 0, 0, 10 ) ):ToScreen();
			
			if ( IM.CVARS.Bools["ESP: Show name"].cvar:GetBool() ) then
				local width, height = surface.GetTextSize( tostring( ply:Nick() ) ); -- I have to do tostring because sometimes errors would occur
				draw.DrawText( ply:Nick(), IM.Font, pos.x, pos.y-height/2, ( IM.IsTTT && ply:IsTraitor() ) and Color( 255, 150, 150, 255 ) or Color( 255, 255, 255, 255 ), 1 );
			end

			if ( IM.IsTTT && IM.CVARS.Bools["ESP: TTT Show traitors"].cvar:GetBool() && ply:IsTraitor() ) then
				local width, height = surface.GetTextSize( "TRAITOR" );
				draw.DrawText( "TRAITOR", IM.Font, pos.x, pos.y-height-3, Color( 255, 0, 0, 255 ), 1 );
			end
			
			pos = ply:GetPos():ToScreen();
			
			if (IM.CVARS.Bools["ESP: Show health"].cvar:GetBool()) then
				local width, height = surface.GetTextSize( "Health: "..tostring( ply:Health() ) );
				draw.DrawText( "Health: "..tostring( ply:Health() ), IM.Font, pos.x, pos.y, color, 1 );
				pos.y = pos.y + 13;
			end
			
			if (IM.CVARS.Bools["ESP: Show weapon"].cvar:GetBool() && IsValid( ply:GetActiveWeapon() )) then
				local width, height = surface.GetTextSize( ply:GetActiveWeapon():GetPrintName() or ply:GetActiveWeapon():GetClass() );
				draw.DrawText( ply:GetActiveWeapon():GetPrintName() or ply:GetActiveWeapon():GetClass(), IM.Font, pos.x, pos.y, Color( 255, 200, 50 ), 1 );
			end
		end
	end
	
	if (IM.IsTTT) then
		if (IM.CVARS.Bools["ESP: TTT Show C4"].cvar:GetBool()) then
			for _, ent in pairs( ents.FindByClass( "ttt_c4" ) ) do
				if (!IM.ply():IsTraitor() or !ent:GetArmed()) then
					local pos = ent:GetPos():ToScreen();
					local width, height = surface.GetTextSize( "C4" );
					
					draw.DrawText( !ent:GetArmed() and "C4 - Unarmed" or "C4 - "..string.FormattedTime(ent:GetExplodeTime() - CurTime(), "%02i:%02i"), IM.Font, pos.x, pos.y-height/2, Color( 255, 200, 200, 255 ), 1 );
				end
			end
		end
		
		if (IM.CVARS.Bools["ESP: TTT Show dead bodies"].cvar:GetBool()) then
			for _, ent in pairs( ents.FindByClass( "prop_ragdoll" ) ) do
				local name = CORPSE.GetPlayerNick( ent, false );
				
				if ( name != false ) then
					local pos = ent:GetPos():ToScreen();
					local width, height = surface.GetTextSize( name );
					
					draw.DrawText( name, IM.Font, pos.x, pos.y-height/2, Color( 255, 255, 255, 255 ), 1 );
					
					if ( !CORPSE.GetFound(ent, false) ) then
						draw.DrawText( "Unidentified", IM.Font, pos.x, pos.y-height/2+12, Color( 200, 200, 0, 255 ), 1 );
					end
				end
			end
		end
	end

	if (IM.IsGmodZ) then
		for _, ent in pairs( ents.FindByClass( "gmodz_item" ) ) do
			if (ent.id) then
				local item = items[ent.id];
				
				if (item) then
					local name = item.name or "ERROR";
					local pos = ent:GetPos():ToScreen();
					local width, height = surface.GetTextSize( name );
					
					draw.DrawText( name, IM.Font, pos.x, pos.y-height/2, Color( 255, 255, 220, 255 ), 1 );
				end
			else
				net.Start( "item_ask_info" );
					net.WriteEntity( ent );
				net.SendToServer();
			end
		end
	end
	
	if (IM.HeadPos != nil) then
		local width = 5;
		local height = 5;
		surface.SetDrawColor( Color( 255, 0, 0, 255 ) );
		surface.DrawOutlinedRect( IM.HeadPos.x-width/2, IM.HeadPos.y-height/2, width, height );
	end
end

function IM.Chams()
	if (IM.CVARS.Bools["Chams"].cvar:GetBool()) then
		for _, ply in pairs( IM.GetPlayersByDistance( ) ) do
			if (ply != IM.ply() && IsValid( ply ) && ply:Alive() && ply:Health() > 0 && ply:Team() != TEAM_SPECTATOR) then
				local color = (IM.IsTTT and ply:IsTraitor( )) and Color( 200, 50, 50 ) or team.GetColor( ply:Team( ) );
				
				cam.Start3D( IM.ply():EyePos(), IM.ply():EyeAngles() );
					render.SuppressEngineLighting( true );

					render.SetColorModulation( color.r/255, color.g/255, color.b/255, 1 );
					render.MaterialOverride( IM.Mat );
					ply:DrawModel();
					
					render.SetColorModulation( IM.AddToColor( color.r, 150 )/255, IM.AddToColor( color.g, 150 )/255, IM.AddToColor( color.b, 150 )/255, 1 );
					if (IsValid( ply:GetActiveWeapon() )) then
						ply:GetActiveWeapon():DrawModel() 
					end
					
					if (IM.IsTTT && ply:IsTraitor()) then
						render.SetColorModulation( 1, 0, 0, 1 );
					else
						render.SetColorModulation( 1, 1, 1, 1 );
					end
					render.MaterialOverride();
					render.SetModelLighting( 4, color.r/255, color.g/255, color.b/255 );
					ply:DrawModel();
					
					render.SuppressEngineLighting( false );
				cam.End3D();
			end
		end
		
		for _, ent in pairs( ents.FindByClass( "ttt_c4" ) ) do
			cam.Start3D( IM.ply():EyePos(), IM.ply():EyeAngles() );
				render.SuppressEngineLighting( true );
				render.SetColorModulation( 1, 0, 0, 1 );
				render.MaterialOverride( IM.Mat );
				ent:DrawModel( );
				
				render.SetColorModulation( 1, 1, 1, 1 );
				render.MaterialOverride();
				render.SetModelLighting( BOX_TOP, 1, 1, 1 )
				ent:DrawModel();
					
				render.SuppressEngineLighting( false );
			cam.End3D();
		end
		
		if (IM.IsTTT) then
			for _, ent in pairs( ents.FindByClass( "prop_ragdoll" ) ) do
				if ( CORPSE.GetPlayerNick(ent, false) != false ) then
					cam.Start3D( IM.ply():EyePos(), IM.ply():EyeAngles() );
						render.SuppressEngineLighting( true );
						render.SetColorModulation( 1, 0.8, 0.5, 1 );
						render.MaterialOverride( IM.Mat );
						ent:DrawModel( );
						
						render.SetColorModulation( 1, 1, 1, 1 );
						render.MaterialOverride();
						render.SetModelLighting( BOX_TOP, 1, 1, 1 )
						ent:DrawModel();
							
						render.SuppressEngineLighting( false );
					cam.End3D();
				end
			end
		end
	end
end

function IM.PlayerDeath( ply )
	IM.PrintChat( Color( 255, 255, 255 ), ply:Nick().." has died!" );
end

timer.Create( IM.TimerName, 0.25, 0, function( )	
	if (!IM.IsTTT || GetRoundState() != 3) then 
		table.Empty( IM.DeadPlayers );
		return;
	end
	
	for _, ply in pairs( IM.players() ) do
		if ((!ply:Alive() || ply:Health() <= 0) && !table.HasValue( IM.DeadPlayers, ply )) then
			table.insert( IM.DeadPlayers, ply );
			IM.PlayerDeath( ply );
		end
	end
end )

function IM.TraitorDetector()
	if (!IM.IsTTT || IM.ply():IsTraitor()) then return end
	
	if (GetRoundState() == 2) then
		for _, wep in pairs(ents.GetAll()) do
			if (wep.CanBuy && wep:IsWeapon() && !table.HasValue(IM.TWeaponsFound, wep:EntIndex())) then
				table.insert( IM.TWeaponsFound, wep:EntIndex() )
			end
		end
	end
	
	if (GetRoundState() != 3 && GetRoundState() != 2) then
		table.Empty( IM.Traitors );
		table.Empty( IM.TWeaponsFound );
		return;
	end
	
	for _, wep in pairs(ents.GetAll()) do
		if (wep:IsWeapon() && wep.CanBuy && IsValid( wep:GetOwner() ) && wep:GetOwner():IsPlayer() && !table.HasValue( IM.TWeaponsFound, wep:EntIndex() )) then
			local ply = wep:GetOwner();
			table.insert( IM.TWeaponsFound, wep:EntIndex() );
			
			if (!ply:IsDetective()) then
				if (!table.HasValue(IM.Traitors, ply)) then
					table.insert(IM.Traitors, ply);
				end
				if (ply != IM.ply() && !IM.ply():IsTraitor() && IM.CVARS.Bools["Traitor Detector"].cvar:GetBool()) then
					chat.AddText( Color( 154, 205, 50 ), "[Ominous]: ",  Color( 255, 50, 50 ), "Weapon: ", Color( 200, 120, 50 ), wep:GetPrintName() or wep:GetClass(),
					chat.AddText( Color( 154, 205, 50 ), "[Ominous]: ",  Color( 255, 120, 50 ), ply:Nick(), Color( 255, 255, 255 ), " has been marked as a  ", Color( 255, 50, 50 ), "Traitor: " ));
				end
			end
		end
	end
end

function IM.AddHook( hookname, name, func )
	table.insert( IM.RandomHooks.hook, hookname );
	table.insert( IM.RandomHooks.name, name );
	hook.Add( hookname, name, func );
end

function IM.Menu( )
	--Creating main stuff
	local UsedCVARS = { };
	
	local Panel = vgui.Create( "DFrame" );
	Panel:SetSize( 500, 300 );
	Panel:SetPos( ScrW()/2-Panel:GetWide()/2, ScrH()/2-Panel:GetTall()/2 );
	Panel:SetTitle( "Ominous Powered v12" );
	Panel:MakePopup();
	
	local SettingsSheet = vgui.Create( "DPropertySheet", Panel );
	SettingsSheet:SetPos( 0, 23 );
	SettingsSheet:SetSize( SettingsSheet:GetParent():GetWide(), SettingsSheet:GetParent():GetTall() - 23 );
	
	local MainPanel = vgui.Create( "DPanel", Panel );
	MainPanel:SetPos( 0, 0 );
	MainPanel:SetSize( MainPanel:GetParent():GetWide(), MainPanel:GetParent():GetTall() - 23 );
	MainPanel.Paint = function() end;
	
	local AimPanel = vgui.Create( "DPanel", Panel );
	AimPanel:SetPos( 0, 0 );
	AimPanel:SetSize( MainPanel:GetParent():GetWide(), MainPanel:GetParent():GetTall() - 23 );
	AimPanel.Paint = function() end;
	AimPanel:SetVisible( false );
	
	local ESPPanel = vgui.Create( "DPanel", Panel );
	ESPPanel:SetPos( 0, 0 );
	ESPPanel:SetSize( MainPanel:GetParent():GetWide(), MainPanel:GetParent():GetTall() - 23 );
	ESPPanel.Paint = function() end;
	ESPPanel:SetVisible( false );
	
	local MiscPanel = vgui.Create( "DPanel", Panel );
	MiscPanel:SetPos( 0, 25 );
	MiscPanel:SetSize( MainPanel:GetParent():GetWide(), MainPanel:GetParent():GetTall() - 23 );
	MiscPanel.Paint = function() end;
	MiscPanel:SetVisible( false );
	
	SettingsSheet:AddSheet("General", MainPanel, "gui/silkicons/user", false, false, "General settings");
	SettingsSheet:AddSheet("Aimbot", AimPanel, "gui/silkicons/user", false, false, "Aimbot settings");
	SettingsSheet:AddSheet("ESP/Chams", ESPPanel, "gui/silkicons/user", false, false, "ESP/Chams settings");
	SettingsSheet:AddSheet("Misc", MiscPanel, "gui/silkicons/user", false, false, "Misc settings");
	--==Main Panel==--
	local Label = vgui.Create( "DLabel", MainPanel );
	Label:SetPos( 10, 5 );
	Label:SetColor( Color( 255, 255, 255, 255 ) );
	Label:SetText( "Settings" );
	Label:SizeToContents();
	
	Label = vgui.Create( "DLabel", MainPanel );
	Label:SetPos( 275, 5 );
	Label:SetColor( Color( 255, 255, 255, 255 ) );
	Label:SetText( "More coming soon" );
	Label:SizeToContents();
	
	local List = vgui.Create( "DPanelList", MainPanel );
	List:SetPos( 10, 20 );
	List:SetSize( 200, 200 );
	List:SetSpacing( 5 );
	List:EnableHorizontal( false );
	List:EnableVerticalScrollbar( true );
	List:SetPadding( 5 );
	function List:Paint()
		draw.RoundedBox( 4, 0, 0, List:GetWide(), List:GetTall(), Color( 0, 0, 0, 150 ) );
	end
	
	table.sort( IM.CVARS.Bools, IM.TableSortByAsc );
	
	for name, base in pairs(IM.CVARS.Bools) do
		if (base.OnMenu && base.main) then
			local CheckBox = vgui.Create( "DCheckBoxLabel" );
			CheckBox:SetText( name );
			CheckBox:SetConVar( base.cvar:GetName() );
			CheckBox:SetValue( base.cvar:GetBool() );
			CheckBox:SizeToContents();
			List:AddItem( CheckBox );
			table.insert( UsedCVARS, base );
		end
	end
	
	List = vgui.Create( "DPanelList", MainPanel );
	List:SetPos( 275, 20 );
	List:SetSize( 200, 200 );
	List:SetSpacing( 5 );
	List:EnableHorizontal( false );
	List:EnableVerticalScrollbar( true );
	List:SetPadding( 5 );
	function List:Paint()
		draw.RoundedBox( 4, 0, 0, List:GetWide(), List:GetTall(), Color( 0, 0, 0, 150 ) );
	end
	--==Aimbot==--
	Label = vgui.Create( "DLabel", AimPanel );
	Label:SetPos( 10, 5 );
	Label:SetColor( Color( 255, 255, 255, 255 ) );
	Label:SetText( "Aimbot settings" );
	Label:SizeToContents();
	
	local List = vgui.Create( "DPanelList", AimPanel );
	List:SetPos( 10, 20 );
	List:SetSize( 200, 200 );
	List:SetSpacing( 5 );
	List:EnableHorizontal( false );
	List:EnableVerticalScrollbar( true );
	List:SetPadding( 5 );
	function List:Paint()
		draw.RoundedBox( 4, 0, 0, List:GetWide(), List:GetTall(), Color( 0, 0, 0, 150 ) );
	end
	
	for name, base in pairs(IM.CVARS.Bools) do
		if (base.OnMenu && !base.main && string.find( base.cvar:GetName(), "aim" )) then
			local CheckBox = vgui.Create( "DCheckBoxLabel" );
			CheckBox:SetText( name );
			CheckBox:SetConVar( base.cvar:GetName() );
			CheckBox:SetValue( base.cvar:GetBool() );
			CheckBox:SizeToContents();
			List:AddItem( CheckBox );
			table.insert( UsedCVARS, base );
		end
	end
	
	local FOVSlider = vgui.Create( "DNumSlider", AimPanel );
	FOVSlider:SetPos( 275, -15 );
	FOVSlider:SetSize( 150, 100 );
	FOVSlider:SetText( "Max Angle" );
	FOVSlider:SetMin( 0 );
	FOVSlider:SetMax( 180 );
	FOVSlider:SetDecimals( 0 );
	FOVSlider:SetConVar( IM.RandomPrefix.."_aimbot_max_angle" );
	FOVSlider.Paint = function()
		draw.RoundedBox( 4, 0, 36, FOVSlider:GetWide(), 25, Color( 0, 0, 0, 150 ) );
	end
	--==ESP==--
	Label = vgui.Create( "DLabel", ESPPanel );
	Label:SetPos( 10, 5 );
	Label:SetColor( Color( 255, 255, 255, 255 ) );
	Label:SetText( "ESP/Chams settings" );
	Label:SizeToContents();
	
	List = vgui.Create( "DPanelList", ESPPanel );
	List:SetPos( 10, 20 );
	List:SetSize( 200, 200 );
	List:SetSpacing( 5 );
	List:EnableHorizontal( false );
	List:EnableVerticalScrollbar( true );
	List:SetPadding( 5 );
	function List:Paint()
		draw.RoundedBox( 4, 0, 0, List:GetWide(), List:GetTall(), Color( 0, 0, 0, 150 ) );
	end
	
	for name, base in pairs(IM.CVARS.Bools) do
		if (base.OnMenu && !base.main && (string.find( base.cvar:GetName(), "esp" ) || string.find( base.cvar:GetName(), "cham" ))) then
			local CheckBox = vgui.Create( "DCheckBoxLabel" );
			CheckBox:SetText( name );
			CheckBox:SetConVar( base.cvar:GetName() );
			CheckBox:SetValue( base.cvar:GetBool() );
			CheckBox:SizeToContents();
			List:AddItem( CheckBox );
			table.insert( UsedCVARS, base );
		end
	end
	--==MISC==--
	Label = vgui.Create( "DLabel", MiscPanel );
	Label:SetPos( 10, 5 );
	Label:SetColor( Color( 255, 255, 255, 255 ) );
	Label:SetText( "Misc settings" );
	Label:SizeToContents();
	
	List = vgui.Create( "DPanelList", MiscPanel );
	List:SetPos( 10, 20 );
	List:SetSize( 200, 200 );
	List:SetSpacing( 5 );
	List:EnableHorizontal( false );
	List:EnableVerticalScrollbar( true );
	List:SetPadding( 5 );
	function List:Paint()
		draw.RoundedBox( 4, 0, 0, List:GetWide(), List:GetTall(), Color( 0, 0, 0, 150 ) );
	end
	
	for name, base in pairs(IM.CVARS.Bools) do
		if (base.OnMenu && !table.HasValue( UsedCVARS, base )) then
			local CheckBox = vgui.Create( "DCheckBoxLabel" );
			CheckBox:SetText( name );
			CheckBox:SetConVar( base.cvar:GetName() );
			CheckBox:SetValue( base.cvar:GetBool() );
			CheckBox:SizeToContents();
			List:AddItem( CheckBox );
		end
	end
end

function IM.UpdateMenu()
	local Panel = vgui.Create( "DFrame" );
	Panel:SetSize( 800, 600 );
	Panel:SetPos( ScrW()/2-Panel:GetWide()/2, ScrH()/2-Panel:GetTall()/2 );
	Panel:SetTitle( "Ominous - Notice" );
	Panel:MakePopup();
	
	local Label = vgui.Create( "DLabel", Panel );
	Label:SetColor( Color( 255, 255, 255, 255 ) );
	Label:SetFont( "DermaLarge" );
	Label:SetText( "Your version is outdated! "..IM.Version );
	Label:SizeToContents();
	Label:SetPos( Label:GetParent():GetWide()/2-Label:GetWide()/2-5, 50 );
	Label.Paint = function()
		Label:SetColor( Color( 255, 255 - (math.sin( CurTime() * 4 ) * 255), 255 - (math.sin( CurTime() * 4 ) * 255), 255 ) );
	end
	
	local HTML = vgui.Create( "HTML", Panel );
	HTML:OpenURL( "" );
	HTML:SetSize( HTML:GetParent():GetWide() - 50, HTML:GetParent():GetTall() - 160 );
	HTML:SetPos( 25, 100 )
	HTML.Paint = function()
		surface.SetDrawColor( Color( 255, 255, 255, 255 ) );
		surface.DrawRect( 0, 0, HTML:GetWide(), HTML:GetTall() );
	end
	
	local Button = vgui.Create( "DButton", Panel );
	Button:SetText( "Save" );
	Button:SetSize( Button:GetParent():GetWide() - 50, 25 );
	Button:SetPos( 25, Button:GetParent():GetTall() - 30 );
	Button.DoClick = function()
		HTML:SetVisible( false );
		Panel:SetSize( 400, 150 );
		Panel:SetPos( ScrW()/2-Panel:GetWide()/2, ScrH()/2-Panel:GetTall()/2 );
		Label:SetText( "Saved to data/ominousv"..IM.V..".txt" );
		Label:SizeToContents();
		Label:SetPos( Label:GetParent():GetWide()/2-Label:GetWide()/2-5, 50 );
		file.Write( "ominousv"..IM.V..".txt", IM.LatestVersion );
	end
end

IM.Init();

IM.AddHook( "RenderScreenspaceEffects" , IM.RandomString( 0, true, true ), IM.Chams );
IM.AddHook( "Think", IM.RandomString( 0, true, true ), IM.Aimbot );
IM.AddHook( "Think", IM.RandomString( 0, true, true ), IM.TraitorDetector );
IM.AddHook( "CreateMove", IM.RandomString( 0, true, true ), IM.CreateMove );
IM.AddHook( "CalcView", IM.RandomString( 0, true, true ), IM.NoVisualRecoil );
IM.AddHook( "HUDPaint", IM.RandomString( 0, true, true ), IM.ESP );

concommand.Add( IM.RandomPrefix.."_unload", function( ply, cmd, args ) 
	for i = 1, #IM.RandomHooks.hook do
		hook.Remove( IM.RandomHooks.hook[i], IM.RandomHooks.name[i] );
		IM.Print( true, true, Color( 255, 255, 255 ), "Unhooked "..IM.RandomHooks.hook[i].." using name "..IM.RandomHooks.name[i] );
	end
	
	concommand.Remove( IM.RandomPrefix.."_unload" );
	concommand.Remove( IM.RandomPrefix.."_menu" );
	concommand.Remove( "+"..IM.RandomPrefix.."_aimbot" );
	concommand.Remove( "-"..IM.RandomPrefix.."_aimbot" );
	concommand.Remove( IM.RandomPrefix.."_aimbot_toggle" );
	timer.Destroy( IM.TimerName );
	IM.Unloaded = true;
	IM.Print( true, true, Color( 255, 255, 255 ), "Unloaded successfully!" );
end );

concommand.Add( IM.RandomPrefix.."_menu", IM.Menu );
concommand.Add( "+"..IM.RandomPrefix.."_aimbot", function( ply, cmd, args )
	IM.AimbotKeyDown = true;
	
	IM.Aimbot();
end );

concommand.Add( "-"..IM.RandomPrefix.."_aimbot", function( ply, cmd, args ) 
	IM.AimbotKeyDown = false;
end );

concommand.Add( IM.RandomPrefix.."_aimbot_toggle", function( ply, cmd, args ) 
	IM.AimbotKeyDown = !IM.AimbotKeyDown;
	IM.ToggleFade = CurTime() + 1.3;
	
	if (IM.AimbotKeyDown == true) then
		IM.Aimbot();
	end
end );